﻿namespace DesignModeConsole.行为型.状态模式.MarioSample;

//状态机实现方案三：状态模式

/// <summary>
/// 状态的接口，定义所有的事件
/// </summary>
public interface IMario
{
    StateEnum GetName();

    /// <summary>
    /// 得到蘑菇
    /// </summary>
    void ObtainMushRoom();

    /// <summary>
    /// 得到斗篷
    /// </summary>
    void ObtainCape();

    /// <summary>
    /// 得到火焰
    /// </summary>
    void ObtainFireFlower();

    /// <summary>
    /// 遇到怪物
    /// </summary>
    void MeetMonster();
}

public class SmallMario : IMario
{
    private readonly MarioStateMachine3 _stateMachine3;

    public SmallMario(MarioStateMachine3 stateMachine3)
    {
        _stateMachine3 = stateMachine3;
    }

    public StateEnum GetName()
    {
        return StateEnum.Small;
    }

    public void ObtainMushRoom()
    {
        _stateMachine3.SetCurrentState(new SuperMario(_stateMachine3));
        _stateMachine3.SetScore(_stateMachine3.Score + 100);
    }

    public void ObtainCape()
    {
        _stateMachine3.SetCurrentState(new CapeMario(_stateMachine3));
        _stateMachine3.SetScore(_stateMachine3.Score + 200);
    }

    public void ObtainFireFlower()
    {
        _stateMachine3.SetCurrentState(new FireMario(_stateMachine3));
        _stateMachine3.SetScore(_stateMachine3.Score + 300);
    }

    public void MeetMonster()
    {
        // 直接挂掉或者做一些事情
    }
}

public class SuperMario : IMario
{
    private readonly MarioStateMachine3 _stateMachine3;

    public SuperMario(MarioStateMachine3 stateMachine3)
    {
        _stateMachine3 = stateMachine3;
    }

    public StateEnum GetName()
    {
        return StateEnum.Super;
    }

    public void ObtainMushRoom()
    {
        // 没有变化
    }

    public void ObtainCape()
    {
        _stateMachine3.SetCurrentState(new CapeMario(_stateMachine3));
        _stateMachine3.SetScore(_stateMachine3.Score + 200);
    }

    public void ObtainFireFlower()
    {
        _stateMachine3.SetCurrentState(new FireMario(_stateMachine3));
        _stateMachine3.SetScore(_stateMachine3.Score + 300);
    }

    public void MeetMonster()
    {
        _stateMachine3.SetCurrentState(new SmallMario(_stateMachine3));
        _stateMachine3.SetScore(_stateMachine3.Score - 100);
    }
}

/// <summary>
/// 斗篷马里奥
/// </summary>
public class CapeMario : IMario
{
    private readonly MarioStateMachine3 _stateMachine3;

    public CapeMario(MarioStateMachine3 stateMachine3)
    {
        _stateMachine3 = stateMachine3;
    }

    public StateEnum GetName()
    {
        return StateEnum.Cape;
    }

    public void ObtainMushRoom()
    {
        // 无操作
    }

    public void ObtainCape()
    {
        // 无操作
    }

    public void ObtainFireFlower()
    {
        // 无操作
    }

    public void MeetMonster()
    {
        _stateMachine3.SetCurrentState(new SmallMario(_stateMachine3));
        _stateMachine3.SetScore(_stateMachine3.Score - 200);
    }
}

public class FireMario : IMario
{
    private readonly MarioStateMachine3 _stateMachine3;

    public FireMario(MarioStateMachine3 stateMachine3)
    {
        _stateMachine3 = stateMachine3;
    }

    public StateEnum GetName()
    {
        return StateEnum.Fire;
    }

    public void ObtainMushRoom()
    {
        // 无操作
    }

    public void ObtainCape()
    {
        // 无操作
    }

    public void ObtainFireFlower()
    {
        // 无操作
    }

    public void MeetMonster()
    {
        _stateMachine3.SetCurrentState(new SmallMario(_stateMachine3));
        _stateMachine3.SetScore(_stateMachine3.Score - 300);
    }
}

public class MarioStateMachine3
{
    /// <summary>
    /// 积分
    /// </summary>
    public int Score { get; private set; }

    /// <summary>
    /// 当前状态
    /// </summary>
    public IMario CurrentState { get; private set; } // 不再使用枚举来表示状态

    public MarioStateMachine3()
    {
        Score = 0;
        CurrentState = new SmallMario(this);
    }

    /// <summary>
    /// 得到蘑菇
    /// </summary>
    public void ObtainMushRoom()
    {
        this.CurrentState.ObtainMushRoom();
    }

    /// <summary>
    /// 得到斗篷
    /// </summary>
    public void ObtainCape()
    {
        this.CurrentState.ObtainCape();
    }

    /// <summary>
    /// 得到火焰
    /// </summary>
    public void ObtainFireFlower()
    {
        this.CurrentState.ObtainFireFlower();
    }

    /// <summary>
    /// 遇到怪物
    /// </summary>
    public void MeetMonster()
    {
        this.CurrentState.MeetMonster();
    }

    /// <summary>
    /// 设置积分
    /// </summary>
    /// <param name="score"></param>
    public void SetScore(int score)
    {
        this.Score = score;
    }

    /// <summary>
    /// 设置状态
    /// </summary>
    /// <param name="currentState"></param>
    public void SetCurrentState(IMario currentState)
    {
        this.CurrentState = currentState;
    }
}